<?php

namespace openai;

class ChatGPT {
    private $api_url = 'https://api.openai.com/v1/chat/completions';
	private $api_key = '';
    private $model = 'gpt-3.5-turbo-0613';
	private $streamHandler;

    private $messageText = '';

	public function __construct($params) {
        if (!empty($params['model'])) {
            $this->model = $params['model'];
        }
        if (!empty($params['api_url'])) {
            $this->api_url = $params['api_url'] . '/v1/chat/completions';
        }

        $this->api_key = $params['api_key'] ?? '';
    }

    public function qa($messages = [])
    {
        // 这行代码用于关闭输出缓冲。关闭后，脚本的输出将立即发送到浏览器，而不是等待缓冲区填满或脚本执行完毕。
        ini_set('output_buffering', 'off');
        // 这行代码禁用了 zlib 压缩。通常情况下，启用 zlib 压缩可以减小发送到浏览器的数据量，但对于服务器发送事件来说，实时性更重要，因此需要禁用压缩。
        ini_set('zlib.output_compression', false);
        // 这行代码使用循环来清空所有当前激活的输出缓冲区。ob_end_flush() 函数会刷新并关闭最内层的输出缓冲区，@ 符号用于抑制可能出现的错误或警告。
        while (@ob_end_flush()) {}
        // 这行代码设置 HTTP 响应的 Content-Type 为 text/event-stream，这是服务器发送事件（SSE）的 MIME 类型。
        header('Content-Type: text/event-stream');
        // 这行代码设置 HTTP 响应的 Cache-Control 为 no-cache，告诉浏览器不要缓存此响应。
        header('Cache-Control: no-cache');
        // 这行代码设置 HTTP 响应的 Connection 为 keep-alive，保持长连接，以便服务器可以持续发送事件到客户端。
        header('Connection: keep-alive');
        // 这行代码设置 HTTP 响应的自定义头部 X-Accel-Buffering 为 no，用于禁用某些代理或 Web 服务器（如 Nginx）的缓冲。
        // 这有助于确保服务器发送事件在传输过程中不会受到缓冲影响。
        header('X-Accel-Buffering: no');
        //echo 'data: '.json_encode(['time'=>date('Y-m-d H:i:s'), 'content'=>'']).PHP_EOL.PHP_EOL;
        //ob_flush();
        //flush();

        $this->streamHandler = new StreamHandler([]);
    	$json = json_encode([
    	    'model' => $this->model,
    	    'messages' => $messages,
    	    'temperature' => 0.6,
    	    'stream' => true,
    	]);

    	$headers = array(
    	    "Content-Type: application/json",
    	    "Authorization: Bearer ".$this->api_key,
    	);

    	$this->openai($json, $headers);
        // 获取消息文本
        $this->messageText = $this->streamHandler->getMessageText();
    }

    // 获取Chat回答
    public function getAnswer()
    {
        return $this->messageText;
    }

    private function openai($json, $headers)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $this->api_url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HEADER, false);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    	curl_setopt($ch, CURLOPT_WRITEFUNCTION, [$this->streamHandler, 'callback']);
        $response = curl_exec($ch);
        curl_close($ch);
    }


    // gpt绘画功能
//    public function gpt_huihua(): void
//    {
//        // 212x212' is not one of ['256x256', '512x512', '1024x1024', '1024x1792', '1792x1024']
//        $api_key = 'sess-zwBN61wlFkiRuGHn8CSs8AXTM44or7tmhw1XJz2c';
//        $info = '一个红裙子少女';
//        $number = 1;
//        $size = '512x512';
//
//        $curl = curl_init();
//        curl_setopt_array($curl, [
//            CURLOPT_URL => 'https://api.openai.com/v1/images/generations',
//            CURLOPT_RETURNTRANSFER => true,
//            CURLOPT_TIMEOUT => 30000,
//            CURLOPT_POST => true,
//            CURLOPT_SSL_VERIFYPEER => false,
//            CURLOPT_HTTPHEADER => [
//                'Content-Type: application/json',
//                'Authorization: Bearer ' . $api_key
//            ],
//            CURLOPT_POSTFIELDS => json_encode([
//                'prompt' => $info,
//                'n' => intval($number),
//                'size' => $size,
//            ])
//        ]);
//        // 请求结束
//        $domain = curl_exec($curl);
////        if ($domain === false) {
////            return response()->json(['data' => '请求失败', 'status' => 401], 401);
////        }
//        curl_close($curl);
//        $domain = json_decode($domain, true);
//
//        $this->success('获取成功', $domain);
//    }
}

